# 系统管理相关视图
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib import messages
from django.core.paginator import Paginator
from django.db.models import Q, Count
from django.http import JsonResponse, HttpResponse
from django.utils import timezone
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
import json
from datetime import datetime, timedelta

from .models import AssetLog, Asset
from .models_system import SystemLog, SystemParameter, DataBackup, SystemNotification


@login_required
@permission_required('assets.view_assetlog', raise_exception=True)
def system_log_list(request):
    """系统日志列表"""
    logs = SystemLog.objects.select_related('user').all()
    
    # 筛选条件
    level_filter = request.GET.get('level')
    module_filter = request.GET.get('module')
    user_filter = request.GET.get('user')
    date_from = request.GET.get('date_from')
    date_to = request.GET.get('date_to')
    search_query = request.GET.get('search')
    
    if level_filter:
        logs = logs.filter(level=level_filter)
    
    if module_filter:
        logs = logs.filter(module=module_filter)
    
    if user_filter:
        logs = logs.filter(user_id=user_filter)
    
    if date_from:
        try:
            date_from_obj = datetime.strptime(date_from, '%Y-%m-%d')
            logs = logs.filter(created_at__gte=date_from_obj)
        except ValueError:
            pass
    
    if date_to:
        try:
            date_to_obj = datetime.strptime(date_to, '%Y-%m-%d')
            logs = logs.filter(created_at__lte=date_to_obj + timedelta(days=1))
        except ValueError:
            pass
    
    if search_query:
        logs = logs.filter(
            Q(message__icontains=search_query) |
            Q(action__icontains=search_query)
        )
    
    # 分页
    paginator = Paginator(logs, 50)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    # 统计信息
    stats = {
        'total': logs.count(),
        'error_count': logs.filter(level='ERROR').count(),
        'warning_count': logs.filter(level='WARNING').count(),
        'today_count': logs.filter(created_at__date=timezone.now().date()).count(),
    }
    
    context = {
        'page_obj': page_obj,
        'stats': stats,
        'level_choices': SystemLog.LOG_LEVEL_CHOICES,
        'module_choices': SystemLog.MODULE_CHOICES,
        'level_filter': level_filter,
        'module_filter': module_filter,
        'user_filter': user_filter,
        'date_from': date_from,
        'date_to': date_to,
        'search_query': search_query,
    }
    
    return render(request, 'assets/system/log_list.html', context)


@login_required
@permission_required('assets.view_assetlog', raise_exception=True)
def asset_log_list(request):
    """资产操作日志列表"""
    logs = AssetLog.objects.select_related('asset', 'operator').filter(is_deleted=False)
    
    # 筛选条件
    asset_filter = request.GET.get('asset')
    action_filter = request.GET.get('action')
    operator_filter = request.GET.get('operator')
    date_from = request.GET.get('date_from')
    date_to = request.GET.get('date_to')
    search_query = request.GET.get('search')
    
    if asset_filter:
        logs = logs.filter(asset_id=asset_filter)
    
    if action_filter:
        logs = logs.filter(action=action_filter)
    
    if operator_filter:
        logs = logs.filter(operator_id=operator_filter)
    
    if date_from:
        try:
            date_from_obj = datetime.strptime(date_from, '%Y-%m-%d')
            logs = logs.filter(created_at__gte=date_from_obj)
        except ValueError:
            pass
    
    if date_to:
        try:
            date_to_obj = datetime.strptime(date_to, '%Y-%m-%d')
            logs = logs.filter(created_at__lte=date_to_obj + timedelta(days=1))
        except ValueError:
            pass
    
    if search_query:
        logs = logs.filter(
            Q(description__icontains=search_query) |
            Q(asset__name__icontains=search_query) |
            Q(asset__asset_number__icontains=search_query)
        )
    
    # 分页
    paginator = Paginator(logs, 50)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    # 统计信息
    stats = {
        'total': logs.count(),
        'today_count': logs.filter(created_at__date=timezone.now().date()).count(),
        'action_stats': logs.values('action').annotate(count=Count('id')).order_by('-count')[:5],
    }
    
    context = {
        'page_obj': page_obj,
        'stats': stats,
        'action_choices': AssetLog.ACTION_CHOICES,
        'asset_filter': asset_filter,
        'action_filter': action_filter,
        'operator_filter': operator_filter,
        'date_from': date_from,
        'date_to': date_to,
        'search_query': search_query,
    }
    
    return render(request, 'assets/system/asset_log_list.html', context)


@login_required
@permission_required('assets.view_assetlog', raise_exception=True)
def asset_log_detail(request, pk):
    """资产日志详情"""
    log = get_object_or_404(AssetLog, pk=pk, is_deleted=False)
    
    context = {
        'log': log,
    }
    
    return render(request, 'assets/system/asset_log_detail.html', context)


@login_required
@permission_required('assets.delete_assetlog', raise_exception=True)
@require_http_methods(["POST"])
def asset_log_delete(request, pk):
    """删除资产操作日志
    - 仅接受 POST
    - AJAX 请求返回 JSON
    - 普通请求使用消息提示并重定向列表页
    """
    log = get_object_or_404(AssetLog, pk=pk, is_deleted=False)

    log_id = log.id
    log.is_deleted = True
    log.save(update_fields=['is_deleted'])

    # 审计日志
    SystemLog.log(
        level='INFO',
        module='assets',
        action='asset_log_soft_delete',
        message=f'软删除资产日志 #{log_id}',
        user=request.user,
        request=request,
        details={'asset_log_id': log_id}
    )

    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({'success': True, 'id': log_id})

    messages.success(request, f'已删除日志 #{log_id}')
    return redirect('assets:asset_log_list')


@login_required
@permission_required('assets.delete_assetlog', raise_exception=True)
@require_http_methods(["POST"])
def asset_log_batch_delete(request):
    """批量软删除资产日志
    接收 POST ids[]=1&ids[]=2 ... 或 ids 为逗号分隔字符串。
    支持 AJAX 返回 JSON。
    """
    ids = request.POST.getlist('ids') or []
    if len(ids) == 1 and ',' in ids[0]:
        ids = [i for i in ids[0].split(',') if i]
    try:
        id_ints = [int(x) for x in ids]
    except (TypeError, ValueError):
        id_ints = []

    qs = AssetLog.objects.filter(id__in=id_ints, is_deleted=False)
    affected = qs.update(is_deleted=True)

    # 审计日志
    if affected:
        SystemLog.log(
            level='INFO',
            module='assets',
            action='asset_log_batch_soft_delete',
            message=f'批量软删除 {affected} 条资产日志',
            user=request.user,
            request=request,
            details={'ids': id_ints, 'affected': affected}
        )

    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({'success': True, 'affected': affected, 'ids': id_ints})

    messages.success(request, f'已删除 {affected} 条日志')
    return redirect('assets:asset_log_list')


@login_required
@permission_required('auth.change_user', raise_exception=True)
def system_parameter_list(request):
    """系统参数列表"""
    parameters = SystemParameter.objects.all()
    
    # 按分组筛选
    group_filter = request.GET.get('group')
    if group_filter:
        parameters = parameters.filter(group=group_filter)
    
    # 搜索
    search_query = request.GET.get('search')
    if search_query:
        parameters = parameters.filter(
            Q(name__icontains=search_query) |
            Q(key__icontains=search_query) |
            Q(description__icontains=search_query)
        )
    
    # 按分组组织参数
    grouped_parameters = {}
    for param in parameters:
        if param.group not in grouped_parameters:
            grouped_parameters[param.group] = []
        grouped_parameters[param.group].append(param)
    
    # 获取所有分组
    all_groups = SystemParameter.objects.values_list('group', flat=True).distinct()
    
    context = {
        'grouped_parameters': grouped_parameters,
        'all_groups': all_groups,
        'group_filter': group_filter,
        'search_query': search_query,
    }
    
    return render(request, 'assets/system/parameter_list.html', context)


@login_required
@permission_required('auth.change_user', raise_exception=True)
def system_parameter_edit(request, pk):
    """编辑系统参数"""
    parameter = get_object_or_404(SystemParameter, pk=pk)
    
    if parameter.is_readonly:
        messages.error(request, '该参数为只读参数，无法修改')
        return redirect('assets:system_parameter_list')
    
    if request.method == 'POST':
        value = request.POST.get('value')
        
        try:
            # 验证参数值
            if parameter.param_type == 'integer':
                int(value)
            elif parameter.param_type == 'float':
                float(value)
            elif parameter.param_type == 'json':
                json.loads(value)
            
            # 更新参数
            parameter.value = value
            parameter.updated_by = request.user
            parameter.save()
            
            # 记录系统日志
            SystemLog.log(
                level='INFO',
                module='system',
                action='parameter_update',
                message=f'更新系统参数: {parameter.name}',
                user=request.user,
                request=request,
                details={'key': parameter.key, 'old_value': parameter.value, 'new_value': value}
            )
            
            messages.success(request, f'参数 {parameter.name} 更新成功')
            return redirect('assets:system_parameter_list')
            
        except (ValueError, json.JSONDecodeError) as e:
            messages.error(request, f'参数值格式错误: {str(e)}')
    
    context = {
        'parameter': parameter,
    }
    
    return render(request, 'assets/system/parameter_edit.html', context)


@login_required
def notification_list(request):
    """用户通知列表"""
    notifications = SystemNotification.objects.filter(
        recipient=request.user
    ).filter(
        Q(expires_at__isnull=True) | Q(expires_at__gt=timezone.now())
    )
    
    # 筛选条件
    is_read = request.GET.get('is_read')
    if is_read == '1':
        notifications = notifications.filter(is_read=True)
    elif is_read == '0':
        notifications = notifications.filter(is_read=False)
    
    notification_type = request.GET.get('type')
    if notification_type:
        notifications = notifications.filter(notification_type=notification_type)
    
    # 分页
    paginator = Paginator(notifications, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    # 统计信息
    stats = {
        'total': notifications.count(),
        'unread': notifications.filter(is_read=False).count(),
        'urgent': notifications.filter(priority='urgent', is_read=False).count(),
    }
    
    context = {
        'page_obj': page_obj,
        'stats': stats,
        'is_read': is_read,
        'notification_type': notification_type,
        'type_choices': SystemNotification.NOTIFICATION_TYPE_CHOICES,
    }
    
    return render(request, 'assets/system/notification_list.html', context)


@login_required
@require_http_methods(["POST"])
def notification_mark_read(request, pk):
    """标记通知为已读"""
    notification = get_object_or_404(SystemNotification, pk=pk, recipient=request.user)
    notification.mark_as_read()
    
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({'success': True})
    
    messages.success(request, '通知已标记为已读')
    return redirect('assets:notification_list')


@login_required
@require_http_methods(["POST"])
def notification_mark_all_read(request):
    """标记所有通知为已读"""
    count = SystemNotification.objects.filter(
        recipient=request.user,
        is_read=False
    ).update(is_read=True, read_at=timezone.now())
    
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({'success': True, 'count': count})
    
    messages.success(request, f'已标记 {count} 条通知为已读')
    return redirect('assets:notification_list')


@login_required
@permission_required('auth.change_user', raise_exception=True)
def data_backup_list(request):
    """数据备份列表"""
    backups = DataBackup.objects.all()
    
    # 分页
    paginator = Paginator(backups, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'page_obj': page_obj,
    }
    
    return render(request, 'assets/system/backup_list.html', context)


@login_required
@permission_required('auth.change_user', raise_exception=True)
def create_backup(request):
    """创建数据备份"""
    if request.method == 'POST':
        name = request.POST.get('name')
        backup_type = request.POST.get('backup_type', 'manual')
        description = request.POST.get('description', '')
        
        # 创建备份记录
        backup = DataBackup.objects.create(
            name=name,
            backup_type=backup_type,
            description=description,
            created_by=request.user,
            status='pending'
        )
        
        # 这里可以添加实际的备份逻辑
        # 例如：调用异步任务执行备份
        
        messages.success(request, f'备份任务 {name} 已创建')
        return redirect('assets:data_backup_list')
    
    return render(request, 'assets/system/backup_create.html')


# 工具函数：记录资产操作日志
def log_asset_action(asset, action, operator, description, request=None, old_value=None, new_value=None, related_object=None):
    """记录资产操作日志的便捷函数"""
    return AssetLog.log_action(
        asset=asset,
        action=action,
        operator=operator,
        description=description,
        old_value=old_value,
        new_value=new_value,
        request=request,
        related_object=related_object
    )


# 工具函数：发送系统通知
def send_notification(recipient, title, message, notification_type='info', priority='medium', sender=None, related_url=None, related_object=None):
    """发送系统通知的便捷函数"""
    return SystemNotification.create_notification(
        recipient=recipient,
        title=title,
        message=message,
        notification_type=notification_type,
        priority=priority,
        sender=sender,
        related_url=related_url,
        related_object=related_object
    )